// <com.woyouqiu.Copyright>
// --------------------------------------------------------------
// <copyright>上海有求网络科技有限公司 2015</copyright>
// <Solution>MyCompany.MyProject</Solution>
// <Project>MyCompany.MyProject.Core</Project>
// <FileName>AgentDomainService.cs</FileName>
// <CreateTime>2017-04-22 23:37</CreateTime>
// <Author>何苗</Author>
// <Email>hemiao@woyouqiu.com</Email>
// <log date="2017-04-22 23:37" version="00001">创建</log>
// --------------------------------------------------------------
// </com.woyouqiu.Copyright>

using System;
using System.Linq;
using System.Runtime.InteropServices.ComTypes;
using System.Threading.Tasks;
using Abp.Domain.Repositories;
using Abp.Runtime.Session;
using Abp.UI;
using Microsoft.AspNetCore.Identity;
using Vecen.BangChuang.Authorization.Users;
using Vecen.BangChuang.BangChuang.Agents;
using Vecen.BangChuang.BangChuang.Areas;
using Vecen.BangChuang.Helpers;

namespace Vecen.BangChuang.BangChuang.DomainServices.Agents {
    public class AgentDomainService: BangChuangDomainServiceBase {

        private readonly IRepository<Agent> _agentRepository;
        private readonly IRepository<City, long> _cityRepository;
        private readonly IRepository<AgentClient> _agentClientRepository;
        private readonly IRepository<AgentApply> _agentApplyRepository;

        public AgentDomainService(IRepository<Agent> agentRepository,
            IRepository<City, long> cityRepository,
            IRepository<AgentClient> agentClientRepository,
            IRepository<AgentApply> agentApplyRepository) {
            _agentRepository = agentRepository;
            _cityRepository = cityRepository;
            _agentClientRepository = agentClientRepository;
            _agentApplyRepository = agentApplyRepository;
        }

        /// <summary>
        /// 获取指定用户的代理商
        /// </summary>
        /// <param name="userId">用户ID</param>
        /// <returns></returns>
        public Task<Agent> GetUserAgentByUserIdAsync(long userId) {
            return Task.Run(() => {
                return _agentClientRepository.GetAllIncluding(c => c.Agent)
                    .FirstOrDefault(c => c.UserId == userId)
                    ?.Agent;
            });
        }

        /// <summary>
        /// 判断某用户是否是代理商
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public Task<bool> IsAgentAsync(long? userId) {
            return Task.Run(() => {
                return _agentRepository.GetAll().Any(c => c.UserId == userId);
            });
        }

        /// <summary>
        /// 获取指定用户的代理商Id
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public Task<int?> GetUserAgentIdByUserIdAsync(long userId) {
            return Task.Run(() => {
                var agentClient = _agentClientRepository.GetAllIncluding(c => c.Agent)
                    .FirstOrDefault(c => c.UserId == userId);
                if(agentClient != null) {
                    return agentClient.AgentId;
                }
                return (int?)null;
            });
        }

        /// <summary>
        /// 根据地区编号获得代理商
        /// </summary>
        /// <param name="areaCode"></param>
        /// <returns></returns>
        public async Task<Agent> GetAgentByAreaCodeAsync(long areaCode) {
            var agent = await _agentRepository.FirstOrDefaultAsync(c => c.AreaCode == areaCode);
            if(agent == null) {
                var city = await _cityRepository.FirstOrDefaultAsync(areaCode);
                if(city != null && city.ParentId.HasValue) {
                    return await GetAgentByAreaCodeAsync(city.ParentId.Value);
                }
                return null;
            }
            return agent;
        }


        /// <summary>
        /// 根据id获得父级代理商
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<Agent> GetParentAgentByIdAsync(int id) {
            var agent = await _agentRepository.FirstOrDefaultAsync(id);
            return await GetParentAgentAsync(agent);
        }

        /// <summary>
        /// 获得父级代理商
        /// </summary>
        /// <param name="agent"></param>
        /// <returns></returns>
        private async Task<Agent> GetParentAgentAsync(Agent agent) {
            var city = await _cityRepository.FirstOrDefaultAsync(agent.AreaCode);
            if(city != null && city.ParentId.HasValue) {
                return await GetAgentByAreaCodeAsync(city.ParentId.Value);
            }
            return null;
        }

        /// <summary>
        /// 根据代理商用户ID获得代理商信息
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public Task<Agent> GetByUserIdAsync(long userId) {
            return _agentRepository.FirstOrDefaultAsync(c => c.UserId == userId && c.IsActive);
        }

        /// <summary>
        /// 获得用户类别
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<string> GetUserTypeAsync(long userId) {
            var agent = await _agentRepository.FirstOrDefaultAsync(c => c.UserId == userId && c.IsActive);
            if(agent != null)
                return agent.UserType;
            var user = UserManager.Users.FirstOrDefault(c => c.Id == userId);
            if(user.IsInner) {
                return UserType.InnerUser;
            }
            return UserType.GeneralUser;
        }

        /// <summary>
        /// 根据申请ID提升申请为正式代理商
        /// </summary>
        /// <param name="applyId"></param>
        /// <returns></returns>
        public async Task<int> PromotionFromApplyAsync(int applyId) {
            var apply = await _agentApplyRepository.FirstOrDefaultAsync(applyId);
            if(apply == null) {
                throw new UserFriendlyException("请求失败!", "店长申请已不存在!");
            }
            var agent = await _agentRepository.FirstOrDefaultAsync(c => c.UserId == apply.UserId);
            if(agent != null) {
                throw new UserFriendlyException("请求失败!", "该用户已经是代理商了!");
            }
            agent = await _agentRepository.FirstOrDefaultAsync(c => c.AreaCode == apply.AreaCode);
            if(agent != null) {
                throw new UserFriendlyException("请求失败!", "该地区已经存在代理商,请先取消!");
            }

            agent = new Agent();
            agent.UserId = apply.UserId;
            agent.AreaCode = apply.AreaCode ?? 0;
            agent.CollegeName = apply.CollegeName;
            agent.IsStudent = apply.IsStudent;
            agent.ParentAgentId = apply.ParentAgentId;
            agent.UniversityName = apply.UniversityName;
            agent.UserType = apply.UserType;
            agent.IsActive = true;
            return await _agentRepository.InsertAndGetIdAsync(agent);
        }

        /// <summary>
        /// 获得提升店长的申请
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<AgentApply> GetApplyByUserIdAsync(long userId) {
            var isAgent = await Task.Run(() => _agentRepository.GetAll().Any(c => c.UserId == userId));
            if(isAgent) {
                return null;
            }
            var agentApply = await _agentApplyRepository.FirstOrDefaultAsync(c => c.UserId == userId);
            return agentApply;
        }

        /// <summary>
        /// 为店长添加用户
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="agentId"></param>
        /// <returns></returns>
        public async Task AddClientToAgentAsync(long userId, int agentId) {
            var agentClient =
                await _agentClientRepository.FirstOrDefaultAsync(c => c.UserId == userId && c.AgentId == agentId);
            if(agentClient == null) {
                await _agentClientRepository.InsertOrUpdateAndGetIdAsync(new AgentClient()
                    {UserId = userId, AgentId = agentId});
            }
        }

        public async Task<Agent> GetAgentLeaderAsync(int? agentId) {
            var agent = await Task.Run(() => _agentRepository.GetAllIncluding(c => c.ParentAgent, c => c.User)
                .FirstOrDefault(c => c.ParentAgentId == agentId || c.Id == agentId));
            return agent?.ParentAgent ?? agent;
        }


        /// <summary>
        /// 获得店长标识字符串
        /// </summary>
        /// <param name="agent"></param>
        /// <returns></returns>
        public Task<string> GetAgentPrimaryKey(Agent agent) {
            var symmetricSecurity = new SymmetricSecurity();
            return Task.Run(() => Uri.EscapeDataString(symmetricSecurity.Encrypto(agent.Id + "|" + agent.UserId)));
        }

        /// <summary>
        /// 获得当前店长标识
        /// </summary>
        /// <returns></returns>
        public async Task<string> GetCurrentAgentPrimaryKeyAsync() {
            var agent = await GetByUserIdAsync(AbpSession.GetUserId());
            if(agent != null) {
                return await GetAgentPrimaryKey(agent);
            }
            agent = await GetUserAgentByUserIdAsync(AbpSession.GetUserId());
            return await GetAgentPrimaryKey(agent);
        }
    }
}